package others;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableOperations {
    static CompletableFuture<Integer> cfi(int i) {
        return CompletableFuture.completedFuture(Integer.valueOf(i));
    }

    public static void main(String[] args) {
        showr(cfi(1));
        voidr(cfi(2).runAsync(() ->
                System.out.println("runAsync")));
        voidr(cfi(3).thenRunAsync(() ->
                System.out.println("thenRunAsync")));
        voidr(CompletableFuture.runAsync(() ->
                System.out.println("runAsync is static")));
        showr(CompletableFuture.supplyAsync(() -> 99));
        voidr(cfi(4).thenAcceptAsync(i ->
                System.out.println("thenAcceptAsync:" + i)));
        showr(cfi(5).thenApplyAsync((i)->i+42));
        showr(cfi(6).thenComposeAsync((i)->cfi(i+99)));
        CompletableFuture<Integer> c = cfi(7);
        //强制更改结果111
        c.obtrudeValue(111);
        showr(c);
        showr(cfi(8).toCompletableFuture());
        c = new CompletableFuture<>();
        c.complete(9);
        showr(c);
        c = new CompletableFuture<>();
        c.cancel(true);
        System.out.println("cancelled:"+c.isCancelled());
        System.out.println("competed exceptionally:"+c.isCompletedExceptionally());
        System.out.println("done:"+c.isDone());
        System.out.println(c);
        c = new CompletableFuture<>();
        c.thenApplyAsync(i->i+42)
                .thenApplyAsync(i->i+12);
        System.out.println("dependents:"+c.getNumberOfDependents());
        c.thenApplyAsync(i->i/2);
        System.out.println("dependents:"+c.getNumberOfDependents());

        //https://github.com/LingCoder/OnJava8/blob/master/docs/book/24-Concurrent-Programming.md#结合-completablefuture
    }


    // Get and show value stored in a CF:
    public static void showr(CompletableFuture<?> c) {
        try {
            System.out.println(c.get());
        } catch (InterruptedException
                | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    // For CF operations that have no value:
    public static void voidr(CompletableFuture<Void> c) {
        try {
            c.get(); // Returns void
        } catch (InterruptedException
                | ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}
